package db.exchange.client;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


import db.exchange.market.ExchangeEngine;
import db.exchange.market.Parser;
import db.exchange.message.Order;
import db.exchange.message.OrderStatus;

public class Transport implements Runnable {
	
	private static final Logger LOG = LogManager.getLogger(ExchangeEngine.class.getName());
	
	Socket requestSocket;

	public BlockingQueue<Order> outQueue = new LinkedBlockingDeque<>();
	public BlockingQueue<Order> inQueue = new LinkedBlockingDeque<>();

	ObjectOutputStream out;
	String loginName;
	Client client;

	public Transport(){}

	public void run() {

		try {
			boolean isConnected = false;
			while (!isConnected) {
				try {
					requestSocket = new Socket("localhost", 2013);
					LOG.info("Connected to localhost in port 2013");
					isConnected = true;
				} catch (UnknownHostException unknownHost) {
					System.err
							.println("You are trying to connect to an unknown host!");
				} catch (ConnectException connectionException) {
					System.err
							.println("Server is not ready, reconnect in 10 seconds ... ");
					try {
						Thread.sleep(10000);
					} catch (InterruptedException e) {
					}

				} catch (IOException ioException) {
					ioException.printStackTrace();

				}
			}
			
			// RUN SocketReader and SocketWriter
			new Thread(new SocketReader(requestSocket)).start();
			new SocketWriter(requestSocket, loginName).run();
			
			System.out.println("Connector quit");
			
		} finally {
			try {
				requestSocket.close();
			} catch (IOException ioException) {
				System.err.println("Can't close the socket.");
			}
		}

	}
	
	public  String acceptER(String message) {
		Parser parser = new Parser();
		String messageType = parser.takeValue(message, "35");
		String text = "";
		switch (messageType) {
		case "A": // logon
			return "Logon successfull";
		case "5": // logout
			text = parser.takeValue(message, "58");
			return "Logon failed: " + text;
		case "8": 
			String orderId = parser.takeValue(message, "11");
			Order order = client.getOrderById(orderId);
			OrderStatus status = OrderStatus.getOrderStatusByIndex(parser
					.takeValue(message, "39"));
			order.setStatus(status);
			
			if (status == OrderStatus.FILLED || status == OrderStatus.PARTFILL) {
				int cumQty = Integer.parseInt(parser.takeValue(message, "14"));
				int leavesQty = Integer.parseInt(parser.takeValue(message,
						"151"));
				order.setLeavesQty(leavesQty);
				order.setCumQty(cumQty);
			}
			if (status == OrderStatus.REJECTED) {
				text = parser.takeValue(message, "58");
			}
			return "Order " + orderId + " is " + status + text;

		default:
			return "Unknown message received";
		}
	}

	public void connect(String host, int port) {
		LOG.info("Client ask for CONNECT");
	}
	
	public void disconnect() {
		LOG.info("Client ask for DISCONNECT");
	}
	
	public void login(String clientName) {
		LOG.info("Client ask for CONNECT");
	}
	
	public void disloginconnect() {
		LOG.info("Client ask for DISCONNECT");
	}
	
	
	public void disconnectByServer(String reason) {
		client.setStatus (ClientStatus.DISCONNECT,reason);
		LOG.info("DISCONNECT",reason);
	}


	
	



}
